package dog

import (
	"encoding/json"
	"github.com/cloudfoundry/gosigar"
	"net/http"
)

type DiskUsage struct {
	sigar.FileSystem
	sigar.FileSystemUsage
}

type Cpus struct {
	sigar.Cpu
	Total    uint64
	Puser    float64
	Pnice    float64
	Psys     float64
	Pidle    float64
	Pwait    float64
	Pirq     float64
	Psoftirq float64
	Pstolen  float64
}

func SigarHttpHandler() (httpHandler func(w http.ResponseWriter, request *http.Request)) {
	handler := SigarStart()
	httpHandler = func(w http.ResponseWriter, request *http.Request) {
		out := handler()
		data, err := json.Marshal(out)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Write(data)
	}
	return httpHandler
}

func SigarStart() (handler func() map[string]interface{}) {
	mem := &sigar.Mem{}
	swap := &sigar.Swap{}
	fslist := &sigar.FileSystemList{}
	uptime := &sigar.Uptime{}
	cpu := &sigar.CpuList{}
	cpus := &Cpus{}
	pids := &sigar.ProcList{}
	load := &sigar.LoadAverage{}
	out := make(map[string]interface{})
	//var df interface{}
	get := func() {
		load.Get()
		pids.Get()
		uptime.Get()
		fslist.Get()
		mem.Get()
		swap.Get()
		cpu.Get()
		df := make([]*DiskUsage, 0)
		for _, f := range fslist.List {
			usage := sigar.FileSystemUsage{}
			usage.Get(f.DirName)
			df = append(df, &DiskUsage{f, usage})
		}
		out["df"] = df

		for _, c := range cpu.List {
			cpus.User += c.User
			cpus.Nice += c.Nice
			cpus.Sys += c.Sys
			cpus.Idle += c.Idle
			cpus.Wait += c.Wait
			cpus.Irq += c.Irq
			cpus.SoftIrq += c.SoftIrq
			cpus.Stolen += c.Stolen
			cpus.Total += c.Total()
		}
		num := uint64(len(cpu.List))
		cpus.User = cpus.User / num
		cpus.Nice = cpus.Nice / num
		cpus.Sys = cpus.Sys / num
		cpus.Idle = cpus.Idle / num
		cpus.Wait = cpus.Wait / num
		cpus.Irq = cpus.Irq / num
		cpus.SoftIrq = cpus.SoftIrq / num
		cpus.Stolen = cpus.Stolen / num
		cpus.Puser = float64((100 * cpus.User) / cpus.Total)
		cpus.Pnice = float64((100 * cpus.Nice) / cpus.Total)
		cpus.Psys = float64((100 * cpus.Sys) / cpus.Total)
		cpus.Pidle = float64((100 * cpus.Idle) / cpus.Total)
		cpus.Pwait = float64((100 * cpus.Wait) / cpus.Total)
		cpus.Pirq = float64((100 * cpus.Irq) / cpus.Total)
		cpus.Psoftirq = float64((100 * cpus.SoftIrq) / cpus.Total)
		cpus.Pstolen = float64((100 * cpus.Stolen) / cpus.Total)
		out["pid_num"] = len(pids.List)
	}

	out["mem"] = mem
	out["swap"] = swap
	out["uptime"] = uptime
	out["cpus"] = &cpu.List
	out["cpu"] = cpus
	out["load"] = load

	handler = func() map[string]interface{} {
		get()
		return out
	}
	return handler
}
